import * as PIXI from 'pixi.js';

function RectBox() {
  const o = new PIXI.Graphics();
  o.cursor = 'pointer';
  return o;
}

export const RectBoxProps = () => ({ visible: true, width: 4, height: 4 });

export function drawRectBox(Params) {
  return function({ dataItem, rectBox }) {
    const lineWidth = Params();
    rectBox.clear();
    rectBox.beginFill('#fff', .01);
    rectBox.lineStyle({ width: lineWidth, color: dataItem.color, alignment: .5 });
    rectBox.drawRect(0, 0, dataItem.width, dataItem.height);
    rectBox.endFill();

    return { dataItem, rectBox };
  };
}

export function drawEyeCatcher(Params) {
  return function({ dataItem, rectBox }) {
    if (!rectBox.eyeCatcher.visible) { return { dataItem, rectBox }; }

    const alpha = Params();
    rectBox.eyeCatcher.clear();
    rectBox.eyeCatcher.beginFill('#fff', alpha);
    rectBox.eyeCatcher.drawRect(0, 0, dataItem.width, dataItem.height);
    rectBox.eyeCatcher.endFill();

    return { dataItem, rectBox };
  }
}

export function drawLabel(Params) {
  return function({ dataItem, rectBox }) {
    if (!rectBox.label.visible) { return { dataItem, rectBox }; }

    const params = Params({ dataItem, rectBox });
    rectBox.label.text = dataItem.label.join(', ');
    rectBox.label.y = params.y;
    Object.assign(rectBox.label.style, params.style);
    rectBox.label.style.lineHeight = rectBox.label.style.fontSize * 1.2;
    rectBox.label.y = rectBox.label.y - rectBox.label.height + rectBox.label.style.fontSize;

    return { dataItem, rectBox };
  }
}

/** 添加醒目块，pointer 停留离开显隐醒目块 */
export const makeEyeCatching = eventMap => ({ xs, rectBox }) => {
  Object.assign(rectBox, { eyeCatcher: new PIXI.Graphics() });
  rectBox.addChild(rectBox.eyeCatcher);
  
  if (eventMap) {
    rectBox.on('pointerenter', event => {
      const dataItem = R.find(R.propEq(rectBox.id, 'id'), xs.value);
      eventMap.pointerenter.pred(dataItem) && eventMap.pointerenter.f(rectBox);
    });
  
    rectBox.on('pointerleave', event => {
      const dataItem = R.find(R.propEq(rectBox.id, 'id'), xs.value);
      eventMap.pointerleave.pred(dataItem) && eventMap.pointerleave.f(rectBox);
    });
  }

  return { xs, rectBox };
}

/** 框上方加标签 */
export function addLabel({ xs, rectBox }) {
  const dataItem = R.find(R.propEq(rectBox.id, 'id'), xs.value);

  Object.assign(rectBox,
    {
      /** 标签 */
      label: new PIXI.Text(dataItem.label.join(', '), {
        fontFamily: '宋体',
        fill: '#fff',
        breakWords: false,
        wordWrap: true,
        dropShadow: true,
        dropShadowBlur: 0,
        dropShadowAngle: Math.PI * .5,
        dropShadowDistance: .5
      })
    },
  );
  rectBox.addChild(rectBox.label);

  return { xs, rectBox };
};

export function useRectBox({ xs, flow, reDraw }) {
  const container = new PIXI.Container();

  function update() {
    // RectBox 不够就创建
    xs.value.forEach((dataItem, i) => {
      const rectBox = R.find(R.propEq(dataItem.id, 'id'), container.children) || container.children[i] || RectBox();
      rectBox.id = dataItem.id;

      if (!container.children[i]) {
        // selectedDataItems 变化会影响 rectBox index
        // 像点击选择这类操作应每次获取对应 dataItem
        flow({ xs, rectBox });
        container.addChild(rectBox);
      }

      // 创框流程里添加了醒目块、标签和控制点这些子元素
      // 画框流程里就是画它自己，醒目块，标签和控制点
      Object.assign(rectBox, R.pick(['visible', 'x', 'y'], dataItem));
      dataItem.visible && reDraw({ dataItem, rectBox });
    });

    // 体现旧数据的框都去掉 id 并隐藏
    R.compose(
      R.forEach(rectBox => Object.assign(rectBox, { id: '', visible: false })),
      R.filter(R.compose( R.not, R.includes(R.__, R.pluck('id', xs.value)), R.prop('id') )),
    )(container.children);
  }

  return { container, update };
}
